#include <Ape/Collections/Array.h>
#include <Ape/EIndexOutOfRange.h>

#include <Ape/MT/Mutex.h>

namespace Ape {
	namespace Collections {
		using Ape::MT::MutexLock;
		
		Array_Impl::Array_Impl (size_t initialSize) : m_Array (NULL), m_Size (initialSize) {
			InitObjectMutex();
			Allocate (initialSize);
		}
		Array_Impl::~Array_Impl() {}
		
		void Array_Impl::Dispose() {
			for (size_t i = 0; i < m_Size; i++) {
				DisposePtr (m_Array[i]);
				m_Array[i] = NULL;
			}
			m_Size = 0;
			m_Allocated = 0;
			del_a (m_Array);
		}
		
		void Array_Impl::Allocate (size_t length) {
			m_Allocated = Helper::CalcAllocateSize (length, sizeof (void*) ) / sizeof (void*);
			m_Array = new void*[m_Allocated];
		}
		
		void* Array_Impl::get (size_t iPos) const {
			MutexLock lock (GetObjectMutex() );
			if (iPos >= m_Size) {
				throw EIndexOutOfRange (L"Index out of range");
			}
			return m_Array[iPos];
		}
		void Array_Impl::set (size_t iPos, void* value) {
			MutexLock lock (GetObjectMutex() );
			if (iPos >= m_Size) {
				throw EIndexOutOfRange (L"Index out of range");
			}
			m_Array[iPos] = value;
		}
		
		size_t Array_Impl::get_Size() const {
			return m_Size;
		}
		size_t Array_Impl::get_Allocated() const {
			return m_Allocated;
		}
	}
}
